import { Component, Host, Input, Output, EventEmitter, ChangeDetectorRef } from "@angular/core";
import { ReportingService, TargetType } from "../../reporting.service";
import { Subscription } from "rxjs";
import { Router, ActivatedRoute } from "@angular/router";
import { CriteriaSummary } from "./template/models/save/criteriaTemplateOutput.interface";
import { BaseTemplateOutput } from "./template/models/save/criteriaTemplateOutput.models";
import * as _ from 'lodash';
import { CriteriaPermissionsComponent } from "./criteriaPermissions.component";

@Component({
    selector: 'criteria',
    templateUrl: 'criteria.component.html',
    styleUrls: ['criteria.component.scss']
})
export class CriteriaComponent extends CriteriaPermissionsComponent {
    private levelsSub: Subscription;
    private changeSub: Subscription;
    private selectAllSub: Subscription;

    public term: string;
    public searchResults: any[];
    public found: boolean;
    public targetType: typeof TargetType = TargetType;

    public criteriaAvailable: boolean;

    @Input() edit: boolean;

    @Input() filterId: string;

    @Input() type: TargetType;

    @Input() level1: string;

    @Input() level2: string;

    public criteriaChanged: EventEmitter<BaseTemplateOutput[]> = new EventEmitter();

    public selectAllAvailability: EventEmitter<boolean> = new EventEmitter();

    public criteria: any[];

    public selectedCriteria: BaseTemplateOutput[] = [];

    public selectedCriteriaSummary: CriteriaSummary[];

    constructor(private toolsService: ReportingService,
        private route: ActivatedRoute,
        private router: Router,
        private cdRef: ChangeDetectorRef) {
            super(cdRef);
    }

    private permissions = {
        "Company Info": true,
        "ESG Risk Rating": this.productPermissions['riskrating'],
        "ESG Rating": this.productPermissions['esg'],
        "Corporate Governance": this.productPermissions['governance'],
        "Global Compact": this.productPermissions['globalcompact'],
        "Controversies": this.productPermissions['controversies'],
        "Sustainable Products": this.productPermissions['sustainableproducts'],
        "Product Involvement": this.productPermissions['productinvolvement']
    };

    ngOnInit() {
        this.toolsService.getCriteriaLevels();

        this.levelsSub = this.toolsService.levels.subscribe(data => {
            this.criteria = data;
            // check permissions to determine which menu options are active
            this.criteria.forEach(criteria => {
                criteria.childItems.forEach(item => {
                    item.baseCriteria.forEach(base => {
                        base.enabled = super.isEnabled(item.shortName, base.name);
                    });
                    item.active = _.find(item.baseCriteria, { enabled: true }) !== undefined;
                });
                criteria.active = _.find(criteria.childItems, { active: true }) !== undefined && this.permissions[criteria.name];
            });
        });

        //on criteria change, update the footer list
        this.changeSub = this.criteriaChanged.subscribe(data => {
            data.forEach(element => {
                let index = this.selectedCriteria.findIndex(x => x.criteriaLevel3Id == element.criteriaLevel3Id);
                if (index > -1)
                    this.selectedCriteria[index] = element;
                else if (element)
                    this.selectedCriteria.push(element);
            });

            this.updateCriteriaSummary();
        });

        this.selectAllSub = this.selectAllAvailability.subscribe(data => {
            this.criteriaAvailable = data;
        });
    }

    ngOnDestroy() {
        this.levelsSub.unsubscribe();
        this.changeSub.unsubscribe();
        this.selectAllSub.unsubscribe();
    }

    public resetCriteria() {
        this.level1 = undefined;
        this.level2 = undefined;
        this.selectedCriteria = [];
        this.selectedCriteriaSummary = [];
    }

    public removeCriteria(criteriaLevel2Id: string, criteriaLevel3Id: string): void {
        this.selectedCriteria.forEach((criteria, index) => {
            if (criteria.criteriaLevel2Id == criteriaLevel2Id) {

                if (criteria.removeCriteriaFromTemplate(criteriaLevel3Id))
                    this.selectedCriteria.splice(index, 1);
            }
        });

        this.updateCriteriaSummary();
    }

    public updateCriteriaSummary() {
        this.selectedCriteriaSummary = [];
        this.selectedCriteria.forEach(element => {
            this.selectedCriteriaSummary = this.selectedCriteriaSummary.concat(element.getTemplateSummary());
        });
    }

    public navigate(route: any[]): void {
        this.router.navigate([{ outlets: { criteria: route } }], { relativeTo: this.route });
    }

    public search() {
        let ret: any[] = [];
        for (var i = 0; i < this.criteria.length; i++) {
            for (var j = 0; j < this.criteria[i].childItems.length; j++) {
                for (var k = 0; k < this.criteria[i].childItems[j].baseCriteria.length; k++) {
                    if (this.criteria[i].childItems[j].baseCriteria[k].name.toLowerCase().indexOf(this.term.toLowerCase()) != -1) {
                        ret.push({
                            id: this.criteria[i].childItems[j].baseCriteria[k].id,
                            name: this.criteria[i].childItems[j].baseCriteria[k].name,
                            shortName: this.criteria[i].childItems[j].shortName,
                            level1: this.criteria[i].id,
                            level2: this.criteria[i].childItems[j].id
                        });
                    }
                }
            }
        }
        this.searchResults = ret;
        this.found = this.searchResults && this.searchResults.length > 0;
    }

    public focusOut(event: any) {
        //not to lose focus before redirecting to the desired criteria
        this.found = event.relatedTarget != null && event.relatedTarget.offsetParent != null && event.relatedTarget.offsetParent.id == 'searchGroup';
    }
    
    public navigateToCriteria(level1: string, level2: string, level3: string, shortName: string, name: string) {
        this.found = false;
        this.level1 = level1;
        this.level2 = level2;        
        this.router.navigate(['/tools', this.type, 'filter', this.filterId, { outlets: { criteria: [this.edit, 'level1', level1, 'level2', level2, 'level3', level3, 'shortName', shortName, 'name', name] } }]);
    }

    public selectAll(e: any, level1: string) {
        let check = e.target.checked;
        if (check)
            //go to select all report page
            this.router.navigate([{ outlets: { criteria: [this.edit, 'level1', level1, 'level2', this.level2, 'all'] } }], { relativeTo: this.route });
        else
            //go to base criteria page for the current tab
            this.router.navigate([{ outlets: { criteria: [this.edit, 'level1', level1, 'level2', this.level2] } }], { relativeTo: this.route });
    }

    showLevel(id) {
        this.level1 = this.level1 !== id ? id : undefined;
    }
}